package zzxkj.blog.shiro;

import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.security.SecurityUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
import zzxkj.blog.pojo.User;
import zzxkj.blog.service.UserService;

/**
 * shiro的realm，用于鉴权
 * @author zzxkj
 */
@Slf4j
@Component
public class AccountRealm extends AuthorizingRealm {

    final
    UserService userService;
    final
    ModelMapper modelMapper;

    public AccountRealm(UserService userService, ModelMapper modelMapper) {
        this.userService = userService;
        this.modelMapper = modelMapper;
    }

    /**
     * （先认证再）
     * 授权authorization
     * */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //拿到用户信息
        AccountProfile profile = (AccountProfile)principals.getPrimaryPrincipal();
        log.info("profile1:{}", profile);
        String userName = profile.getUsername();
        //如果不是admin，则角色为游客，null
        if(!userService.isAdminUser(userName)){
            log.info("{} is guest}", userName);
            return null;
        }
        log.info("{} is admin}", userName);
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //赋予管理员角色，shiro内置有admin、guest
        simpleAuthorizationInfo.addRole("admin");
        return simpleAuthorizationInfo;
    }
    /**
     *认证authentication
     * */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)token;
        // 数据库验证
        User user = userService.login(usernamePasswordToken.getUsername(), String.valueOf(usernamePasswordToken.getPassword()));
        AccountProfile profile = new AccountProfile();
        modelMapper.map(user, profile);
        // principal就是用户信息
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(profile, token.getCredentials(), getName());
        // session存放信息
        Subject currentSubject=SecurityUtils.getSubject();
        currentSubject.getSession().setAttribute("user", user);
        return authenticationInfo;
    }
}
